package com.iisigroup.http.test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.util.EntityUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public abstract  class BaseCommonHttpMethod {
	private final static Logger LOGGER = LoggerFactory.getLogger(BaseCommonHttpMethod.class);
	abstract ResponseResult testMethod() throws Exception;
	abstract int getThreadNum();
	
	
	 
	public String extractString(final String content,final String regExpress){
    	final	Matcher matcher = Pattern.compile(regExpress).matcher(content);
    	if(matcher.find()){
    		return matcher.group(matcher.groupCount());
    	}
    	return null;
    }
	 public CloseableHttpClient getHttpClient(final String proxyIp,final int  port ) {
	        try {
	        	final SSLConnectionSocketFactory sslsf = getSSLConnectionSocketFactory();
	        	if(StringUtils.isBlank(proxyIp)){
	        		
	    			final CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf) .build();
	    			return httpclient;
	        	}else{        		
//	        		final HttpHost proxy = new HttpHost("172.16.0.14", 3128);
	        		final HttpHost proxy = new HttpHost(proxyIp, port);
	    			final DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
	    			final CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).setRoutePlanner(routePlanner).build();
	                
	                return httpclient;
	        	} 
	        } catch (Exception e) {
	            e.printStackTrace();
	            return HttpClients.createDefault();
	        }
	    }

	    public SSLConnectionSocketFactory getSSLConnectionSocketFactory() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException {
	        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
	            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
	                return null;
	            }

	            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
	            }

	            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
	            }
	        } };
	        SSLContext sslContext = SSLContext.getInstance("SSL");
	        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
	        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new TrustingHostnameVerifier());
	        return sslsf;
	    }

	    private static final class TrustingHostnameVerifier implements X509HostnameVerifier {
	        public boolean verify(String hostname, SSLSession session) {
	            return true;
	        }
	        @Override
	        public void verify(String host, SSLSocket ssl) throws IOException {
	        }
	        @Override
	        public void verify(String host, X509Certificate cert) throws SSLException {
	        }
	        @Override
	        public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
	        }
	    } 
	    public void getResponseByGet(final  org.apache.http.client.HttpClient httpclient , final String... urls){
	    	for(String url : urls){
	    		 final HttpGet httpGet = new HttpGet(url);
				try {
					final HttpResponse response1 = httpclient.execute(httpGet);
					final HttpEntity entity1 = response1.getEntity();
		            EntityUtils.consume(entity1);
				} catch (ClientProtocolException e) {
					LOGGER.error(e.getMessage(),e);				
				} catch (IOException e) {
					LOGGER.error(e.getMessage(),e);
				}
	            
	    	}
	    }
	    
	    public String halfToCFull(String number){    	
	    	if (number .equals("1"))
	    		number = "一";
	    	else if (number .equals("2"))
	    		number = "二";
	    	else if (number .equals( "3"))
	    		number = "三";
	    	else if (number .equals( "4"))
	    		number = "四";
	    	else if (number .equals( "5"))
	    		number = "五";
	    	else if (number .equals( "6"))
	    		number = "六";
	    	else if (number .equals( "7"))
	    		number = "七";
	    	else if (number .equals( "8"))
	    		number = "八";
	    	else if (number .equals( "9"))
	    		number = "九";
	    	else if (number .equals( "0"))
	    		number = "零";
	    	return number;
	    }
	    public String halfToFull(String number){
	    	if (number .equals( "1"))
	    		number = "１";
	    	else if (number .equals( "2"))
	    		number = "２";
	    	else if (number .equals( "3"))
	    		number = "３";
	    	else if (number .equals( "4"))
	    		number = "４";
	    	else if (number .equals( "5"))
	    		number = "５";
	    	else if (number .equals( "6"))
	    		number = "６";
	    	else if (number .equals( "7"))
	    		number = "７";
	    	else if (number .equals( "8"))
	    		number = "８";
	    	else if (number .equals( "9"))
	    		number = "９";
	    	else if (number .equals( "0"))
	    		number = "０";
	    	return number;	
	    }
	    public String convert(String str ,String ConvertType){
	    	String a = "";
	    	String b = "";
	    	int len = str.length();

	    	if (len > 0  ) {
	    		for ( int i = 0; i < len; i++) {
	    			a = String.valueOf(str.charAt(i));
	    			if (ConvertType.equals("C"))
	    				a = halfToCFull(a);
	    			else if (ConvertType.equals("N"))
	    				a = halfToFull(a);

	    			b = b + a;
	    		}
	    		str = b;
	    	}
	    	return str;
	    }
	    public void multiProcess() {
	        List<Future<ResponseResult>> data = null;
	        final List<HttpTask> tasks = new ArrayList<HttpTask>();
	        for (int j = 0; j < 100000; ++j) {
	            tasks.add(new HttpTask());
	        }
	        //		ExecutorService service = Executors.newCachedThreadPool();
	        ExecutorService service = Executors.newFixedThreadPool(getThreadNum());

	        try {
	            data = service.invokeAll(tasks, 10000, TimeUnit.SECONDS);
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        } finally {
	            service.shutdown();
	        }
	        final List<ResponseResult> finalData = new ArrayList<ResponseResult>();
	        if (data != null && data.size() > 0) {
	            for (Future<ResponseResult> futureUnit : data) {
	                try {
	                	ResponseResult rr =  futureUnit.get();
	                	finalData.add(rr);
	                } catch (Exception e) {
	                	LOGGER.error(e.getMessage(), e);
	                }
	            }
	        }
	        int wrongCount =0;
	        long total =0l;
	        int countResponse =0;
	    	final List<Record> record  =new ArrayList<Record>(); 
	        for(ResponseResult rr  : finalData){
	        	total+=rr.getAverageTime();
	        	countResponse +=	rr.getListResult().size();
	        	if(!rr.isValidation()){
	        		wrongCount++;
	        		final List<Record> list = rr.getWrongValidationRec();
	        		record.addAll(list);
	        	}
	        }
	        long num = (long)finalData.size();
	        LOGGER.info("average time: {}",String.valueOf((total/num)/ 1.0e3)) ;
	        LOGGER.info("執行筆數: {}",countResponse) ;
	        LOGGER.info("非預期結果比數 :{}",wrongCount) ;
	        LOGGER.info("-----------------------") ;
	        for(Record rr :record){
				LOGGER.info("persojn_id: {}", rr.getPersonId());
				LOGGER.info("第一次response \r\n: {}", rr.getContent1st());
				LOGGER.info("第二次response \r\n: {}", rr.getContent2nd());
				LOGGER.info("-----------------------");
	        }
	    }

	    public class HttpTask implements Callable<ResponseResult> {
	        @Override
	        public ResponseResult call() throws Exception {
	            return testMethod();
	        }
	    }
	    
}
